// 导入参数验证中间件
const { body, param, query, validationResult } = require("express-validator");
// 将需要验证的参数保存为对象，以便重用。
const validators = {
  username: body("username")
    .trim()
    .isLength({ min: 3, max: 16 })
    .withMessage("用户名长度必须在3到16个之间"),
  oldPassword: body("oldPassword")
    .trim()
    .isLength({ min: 6, max: 20 })
    .withMessage("原密码长度在6到20个之间"),
  password: body("password")
    .trim()
    .isLength({ min: 6, max: 20 })
    .withMessage("密码长度在6到20个之间"),
  confirmPassword: body("confirmPassword")
    .trim()
    .isLength({ min: 6, max: 20 })
    .withMessage("密码长度在6到20个之间")
    .custom((val, { req }) => {
      if (val != req.body.password) throw new Error("两次密码输入必须一致");
      return true;
    }),
  nickname: body("nickname")
    .notEmpty()
    .withMessage("昵称不能为空")
    .isLength({ max: 50 })
    .withMessage("昵称不能超过50个字符"),
  title: body("title")
    .notEmpty()
    .withMessage("标题不能为空")
    .isLength({ max: 100 })
    .withMessage("标题不能超过100个字符")
    .trim()
    .escape(),
  description: body("description")
    .isLength({ max: 255 })
    .withMessage("待办描述不应该超过255个字符")
    .trim()
    .escape(),
  priority: body("priority")
    .notEmpty()
    .isIn(["normal", "important", "crucial"])
    .withMessage("优先级参数错误"),
  todoId: param("tid").notEmpty().toInt(),
  limit: query("limit").optional().toInt(),
  offset: query("offset").optional().toInt(),
};

/**
 * validate 高阶函数：根据验证器生成中间件
 *
 * @param {array} validators 验证器数组
 * @returns {function} Express的中间件
 */
const validate = (...validators) => {
  return async (req, res, next) => {
    await Promise.all(validators.map((v) => v.run(req)));
    const errors = validationResult(req);
    if (errors.isEmpty()) {
      return next();
    }
    let err = {};
    for (let e of errors.array()) {
      if (e.param in err) err[e.param].push(e.msg);
      else err[e.param] = [e.msg];
    }
    res.json({ success: false, errors: err });
  };
};

module.exports = { validators, validate };
